package com.team.merchant.mq;

import com.team.merchant.config.CacheSyncConfig;
import com.team.merchant.domain.vo.RabbitDetailVo;
import com.team.merchant.service.StatsService;
import com.team.merchant.service.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
@Slf4j
public class CacheSyncConsumer {
    // Redis Key常量
    private static final String GLOBAL_STATS_KEY = "stats:summary";
    private static final String ORDER_BY_TYPE_KEY = "stats:orders_by_type";
    private static final String REVENUE_PREFIX = "stats:revenue:";
    private static final String LEADERBOARD_KEY = "stats:leaderboard";
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    @Autowired
    private StatsService statsService;
    
    @Autowired
    private WebSocketService webSocketService;
    
    @PostConstruct
    public void init() {
        System.out.println("=====================================");
        System.out.println("CacheSyncConsumer 初始化完成，开始监听 " + CacheSyncConfig.MERCHANT_QUEUE + " 队列");
        System.out.println("=====================================");
    }
    
    @RabbitListener(queues = "#{cacheSyncQueue.name}")
    public void receiveOrderMessage(RabbitDetailVo rabbitDetailVo) {
        System.out.println("===============================================");
        System.out.println("接收到订单消息: " + rabbitDetailVo);
        
        log.info("===============================================");
        log.info("接收到订单消息: {}", rabbitDetailVo);
        log.info("接收到订单消息详情: orderId={}, serviceType={}, amount={}, operation={}, timestamp={}",
                rabbitDetailVo.getOrderId(),
                rabbitDetailVo.getServiceType(),
                rabbitDetailVo.getAmount(),
                rabbitDetailVo.getOperation(),
                rabbitDetailVo.getTimestamp());
        
        // 检查必要字段是否为空
        if (rabbitDetailVo.getServiceType() == null || rabbitDetailVo.getServiceType().isEmpty()) {
            log.error("服务类型为空，无法更新Redis");
            System.out.println("服务类型为空，无法更新Redis");
            return;
        }
        
        if (rabbitDetailVo.getAmount() == null) {
            log.error("金额为空，无法更新Redis");
            System.out.println("金额为空，无法更新Redis");
            return;
        }
        
        // 1. 数据准备（金额转换为分处理）
        String serviceType = rabbitDetailVo.getServiceType();
        long amountInCents = convertToCents(rabbitDetailVo.getAmount());
        
        log.info("准备更新Redis | 服务类型: {} | 金额: {}分", serviceType, amountInCents);
        System.out.println("准备更新Redis | 服务类型: " + serviceType + " | 金额: " + amountInCents + "分");
        
        try {
            boolean connectionStatus = !redisTemplate.getConnectionFactory().getConnection().isClosed();
            log.info("Redis连接状态: {}", connectionStatus ? "正常" : "已关闭");
            System.out.println("Redis连接状态: " + (connectionStatus ? "正常" : "已关闭"));
            
            // 测试Redis连接
            Boolean testResult = redisTemplate.hasKey("test_key");
            log.info("Redis连接测试结果: {}", testResult);
            System.out.println("Redis连接测试结果: " + testResult);
            
            // 设置一个测试键值对
            redisTemplate.opsForValue().set("test_key", "test_value");
            String testValue = redisTemplate.opsForValue().get("test_key");
            System.out.println("Redis测试键值对: " + testValue);
            
            // 2. 执行Redis事务操作
            Object result = redisTemplate.execute(new SessionCallback<Object>() {
                @Override
                public Object execute(RedisOperations operations) {
                    operations.multi();  // 开启事务

                    // 3. 更新全局统计
                    operations.opsForHash().increment(GLOBAL_STATS_KEY, "total_orders", 1);
                    operations.opsForHash().increment(GLOBAL_STATS_KEY, "total_revenue", amountInCents);

                    // 4. 更新分类订单量（Sorted Set）
                    operations.opsForZSet().incrementScore(ORDER_BY_TYPE_KEY, serviceType, 1);

                    // 5. 更新分类收入（String）
                    String revenueKey = REVENUE_PREFIX + serviceType;
                    operations.opsForValue().increment(revenueKey, amountInCents);

                    // 6. 更新收入排行榜（Sorted Set）
                    operations.opsForZSet().incrementScore(LEADERBOARD_KEY, serviceType, amountInCents);

                    return operations.exec();  // 提交事务
                }
            });

            log.info("Redis事务执行结果: {}", result);
            System.out.println("Redis事务执行结果: " + result);
            log.info("Redis更新成功 | 服务类型: {} | 金额: {}分", serviceType, amountInCents);
            System.out.println("Redis更新成功 | 服务类型: " + serviceType + " | 金额: " + amountInCents + "分");
            
            // 查询更新后的数据
            Object totalOrders = redisTemplate.opsForHash().get(GLOBAL_STATS_KEY, "total_orders");
            Object totalRevenue = redisTemplate.opsForHash().get(GLOBAL_STATS_KEY, "total_revenue");
            Double typeOrders = redisTemplate.opsForZSet().score(ORDER_BY_TYPE_KEY, serviceType);
            String typeRevenue = redisTemplate.opsForValue().get(REVENUE_PREFIX + serviceType);
            Double leaderboardScore = redisTemplate.opsForZSet().score(LEADERBOARD_KEY, serviceType);
            
            log.info("更新后的Redis数据:");
            log.info("总订单数: {}", totalOrders);
            log.info("总收入: {}", totalRevenue);
            log.info("{}订单数: {}", serviceType, typeOrders);
            log.info("{}收入: {}", serviceType, typeRevenue);
            log.info("{}排行榜分数: {}", serviceType, leaderboardScore);
            
            System.out.println("更新后的Redis数据:");
            System.out.println("总订单数: " + totalOrders);
            System.out.println("总收入: " + totalRevenue);
            System.out.println(serviceType + "订单数: " + typeOrders);
            System.out.println(serviceType + "收入: " + typeRevenue);
            System.out.println(serviceType + "排行榜分数: " + leaderboardScore);
            
            // Redis更新后，发送WebSocket消息
            webSocketService.sendStatsUpdate(statsService.getLatestStats());
            
        } catch (Exception e) {
            log.error("Redis更新失败 | 服务类型: {} | 错误类型: {} | 错误信息: {}", 
                    serviceType, e.getClass().getName(), e.getMessage());
            System.out.println("Redis更新失败 | 服务类型: " + serviceType + " | 错误类型: " + e.getClass().getName() + " | 错误信息: " + e.getMessage());
            e.printStackTrace();
            // 此处可添加重试或补偿逻辑
        }
        log.info("===============================================");
        System.out.println("===============================================");
    }
    
    // 金额转换方法（元转分）
    private long convertToCents(Double amount) {
        return (long) (amount * 100);
    }
}
